package cn.huiyunche.base.service.interfaces.impl;


import cn.huiyunche.base.service.enums.FaceCompareResult;
import cn.huiyunche.base.service.interfaces.DriverCompareService;
import cn.huiyunche.base.service.model.DCompareFaceResult;
import cn.huiyunche.base.service.utils.HttpRequestUtil;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import com.google.gson.Gson;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by qichao on 2017/3/2.
 */
@Service
public class DriverCompareServiceImpl implements DriverCompareService {

    private static final Logger LOGGER = LoggerFactory.getLogger(DriverCompareServiceImpl.class);

    //@Value("${faceplusplus.compare.api}")
    private String faceplusplus_compare_api;

    //@Value("${faceplusplus.api.key}")
    private String faceplusplus_api_key;

    //@Value("${faceplusplus.api.secret}")
    private String faceplusplus_api_secret;

    @Override
    public DCompareFaceResult compareFaceApi(String sourceImageUrl, String targetImageUrl) throws BusinessException {
        LOGGER.info("DriverCompareServiceImpl.compareFaceApi params : {}, {}", sourceImageUrl, targetImageUrl);
        DCompareFaceResult result = new DCompareFaceResult();
        if (StringUtils.isBlank(sourceImageUrl)) {
            LOGGER.error("DriverCompareServiceImpl.compareFaceApi param imageSourceKey must not be null");
            result.setErrorMsg("需要比对的图片不能为空");
            result.setMsgCode("600");
            return result;
        }
        if (StringUtils.isBlank(targetImageUrl)) {
            LOGGER.error("DriverCompareServiceImpl.compareFaceApi param imageTargetKey must not be null");
            result.setErrorMsg("比对图片不能为空");
            result.setMsgCode("700");
            return result;

        }

        //组装请求参数
        Map params = new HashMap<String, String>();
        params.put("api_key", faceplusplus_api_key);
        params.put("api_secret", faceplusplus_api_secret);
        params.put("image_url1", sourceImageUrl);
        params.put("image_url2", targetImageUrl);

        //调用接口
        String returnValue = HttpRequestUtil.sendHttpPost(faceplusplus_compare_api, params, 10000);

        return this.dCompareFaceResult(returnValue);
    }

    @Override
    public void verifyThatTheDriverIsHe(Long waybillId, String sourceImageToken, String targetImageToken) {
        LOGGER.info("DriverCompareServiceImpl.verifyThatTheDriverIsHe params : {}, {}, {}", waybillId, sourceImageToken, targetImageToken);

        if (null == waybillId || 0 == waybillId.longValue()) {
            LOGGER.error("DriverCompareServiceImpl.verifyThatTheDriverIsHe param waybillId must not be null");
            throw new IllegalArgumentException("运单主键不能为空");
        }
        if (StringUtils.isBlank(sourceImageToken)) {
            LOGGER.error("DriverCompareServiceImpl.verifyThatTheDriverIsHe param sourceImageToken must not be null");
            throw new IllegalArgumentException("需要比对的图像不能为空");
        }
        if (StringUtils.isBlank(targetImageToken)) {
            LOGGER.error("DriverCompareServiceImpl.verifyThatTheDriverIsHe param targetImageToken must not be null");
            throw new IllegalArgumentException("比对的图像不能为空");
        }

        //比较
    }

    private DCompareFaceResult dCompareFaceResult(String returnValue) {
        LOGGER.info("DriverCompareServiceImpl.handleTheReturnValue param : {}", returnValue);

        DCompareFaceResult result = new DCompareFaceResult();
        result.setIsSelf(false);
        result.setMsgCode("400");
        result.setErrorMsg("比对失败");


        Map<String, Float> thresholds = new HashMap<>();

        Gson gson = new Gson();
        HashMap map = gson.fromJson(returnValue, HashMap.class);
        String error_messagecode = map.get("messagecode").toString();
        FaceCompareResult data;
        if ("200.0".equals(error_messagecode)) {
            data = gson.fromJson(map.get("data").toString(), FaceCompareResult.class);
        } else {
            result.setIsSelf(false);
            result.setMsgCode(error_messagecode);
            result.setErrorMsg("比对失败");
            return result;

        }
        Float confidence;

        //判断是否检测到两张图片的人脸
        if(CollectionUtils.isEmpty(data.getFaces1())){
            result.setIsSelf(false);
            result.setMsgCode(error_messagecode);
            result.setErrorMsg("未检测到采集图片人脸");
            return result;
        }
        if(CollectionUtils.isEmpty(data.getFaces2())){
            result.setIsSelf(false);
            result.setMsgCode(error_messagecode);
            result.setErrorMsg("未检测到交车图片人脸");
            return result;
        }


        //如果传入图片但图片中未检测到人脸，则无法进行比对，本字段不返回
        confidence = data.getConfidence();

        //如果传入图片但图片中未检测到人脸，则无法进行比对，本字段不返回
        thresholds = data.getThresholds();

        //如果未使用image_url1或image_file1传入图片，本字段不返回
//        String image_id1 = data.getImage_id1();

        //如果未使用image_url2或image_file2传入图片，本字段不返回
//        String image_id2 = data.getImage_id2();

        //当请求失败时才会返回此字符串，具体返回内容见后续错误信息章节。否则此字段不存在
        if (StringUtils.isNotBlank(data.getError_message())) {
            LOGGER.error("DriverCompareServiceImpl.handleTheReturnValue confidence request error");
            result.setMsgCode("500");
            result.setErrorMsg(data.getError_message());
        } else {
            if (null == confidence || MapUtils.isEmpty(thresholds)) {
                LOGGER.error("DriverCompareServiceImpl.handleTheReturnValue confidence or thresholds is null");
            } else {

                //误识率为千分之一的置信度阈值
                String min_threshold = String.valueOf(thresholds.get("1e-3"));

                //误识率为万分之一的置信度阈值
//                Float mid_threshold = thresholds.get("1e-4");

                //误识率为十万分之一的置信度阈值
//                Float max_threshold = thresholds.get("1e-5");

                if (null != min_threshold) {
                    if (-1 != confidence.compareTo(Float.parseFloat(min_threshold))) {
                        result.setIsSelf(true);
                        result.setMsgCode("200");
                        result.setErrorMsg("比对成功");
                    }

                }
            }

        }

        return result;
    }

}
